package com.niodata.dp.expression.function.array;

import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorObject;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ArrayRegexFilterFunction extends AbstractFunction {

  @Override
  public String getName() {
    return "array.re_filter";
  }

  /**
   * test array contains some value.
   *
   * @param env env
   * @param array array
   * @param regex regex pattern
   * @return contains or not
   */
  public AviatorObject call(Map<String, Object> env, AviatorObject array, AviatorObject regex) {
    Object v = array.getValue(env);
    List<Object> list = null;
    if (List.class.isAssignableFrom(v.getClass())) {
      list = (List) v;
    } else if (v.getClass().isArray()) {
      int len = Array.getLength(v);
      list = new ArrayList<>(len);
      for (int i = 0; i < len; i++) {
        Object value = Array.get(v, i);
        list.add(value);
      }
    }
    List<Object> result = new ArrayList<>();
    String re = regex.getValue(env).toString();
    for (Object value : list) {
      if (value != null && value.toString().matches(re)) {
        result.add(value);
      }
    }
    if (v.getClass().isArray()) {
      Object[] varray = new Object[result.size()];
      for (int i = 0; i < result.size(); i++) {
        varray[i] = result.get(i);
      }
      return FunctionUtils.wrapReturn(varray);
    } else {
      return FunctionUtils.wrapReturn(result);
    }
  }
}
